package server.net;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.*;

public class Server implements Runnable {

	private Selector selector;
	private ServerSocketChannel serverSocketChannel;
	private boolean running = true;

	public Server(int port) {
		try {
			System.out.print("Attempting to start server on port: [" + port + "]... ");
			selector = Selector.open();
			serverSocketChannel = ServerSocketChannel.open();
			serverSocketChannel.configureBlocking(false);
			serverSocketChannel.socket().bind(new InetSocketAddress(port));
			serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
			System.out.println("Successfully started!");
		} catch (IOException e) {
			System.out.println("Error starting!");
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		while (running) {
			try {
				selector.select();
				for (SelectionKey selectionKey : selector.selectedKeys()) {
					if (!selectionKey.isValid()) {
						continue;
					}
					if (selectionKey.isAcceptable()) {
						SocketChannel socket = serverSocketChannel.accept();
						System.out.print("Attempting to accept connection from: [" + socket.socket().getInetAddress() + "]... ");
						socket.configureBlocking(false);
						SelectionKey key = socket.register(selector, SelectionKey.OP_READ);
						PlayerChannel playerChannel = new PlayerChannel((SocketChannel) key.channel());
						key.attach(playerChannel);
						System.out.println("Successfully accepted!");
					} else if (selectionKey.isReadable()) {
						((PlayerChannel)selectionKey.attachment()).handleIncomingData();
					}
				}
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public void setRunning(boolean running) {
		this.running = running;
	}

}